from collections.abc import MutableMapping
from copy import deepcopy
from pprint import pformat

from bald_spider.exceptions import ItemInitError, ItemAttributeError
from bald_spider.items import Field, ItemMeta


class Item(MutableMapping, metaclass=ItemMeta):
    FIELDS: dict  # 用于保存field

    def __init__(self, *args, **kwargs):
        self._value = {}
        if args:
            raise ItemInitError(f"{self.__class__.__name__}: position args is not supported. use keyword args")
        if kwargs:
            for k, v in kwargs.items():
                self[k] = v

    def __setitem__(self, key, value):
        if key in self.FIELDS:
            self._value[key] = value
        else:
            raise KeyError(f"{self.__class__.__name__} does no support field {key}")

    def __getitem__(self, key):
        return self._value[key]

    def __delitem__(self, key):
        del self._value[key]

    def __setattr__(self, key, value):
        if not key.startswith('_'):
            raise AttributeError(f"use item[{key!r}] = {value!r} to set field value ")
        super().__setattr__(key, value)

    def __getattr__(self, item):
        raise AttributeError(
            f"{self.__class__.__name__} does no support field {item},please add the `{item}` to {self.__class__.__name__}, and use item[{item}] to get field value")

    def __getattribute__(self, item):
        fields = super().__getattribute__('FIELDS')
        if item in fields:
            raise ItemAttributeError(f"use item[{item}] to get field value ")
        else:
            return super().__getattribute__(item)

    def __len__(self):
        return len(self._value)

    def __iter__(self):
        return iter(self._value)

    def __repr__(self):
        return pformat(dict(self))

    __str__ = __repr__

    def to_dict(self):
        return dict(self)

    def copy(self):
        return deepcopy(self)


# if __name__ == '__main__':
#     class TestItem(Item):
#         url = Field()
#         title = Field()
#
#
#     test = TestItem(url='11111')
#     print(test['url'])
